﻿using System;
using System.Linq;
using Microsoft.Xna.Framework.Input;

namespace LoA.Shared.Input {
	/// <summary>
	/// Helper class for working with the 8-way directions stored in a Buttons enum.
	/// </summary>
	public static class InputDirection {
		// Helper bit masks for directions defined with the Buttons flags enum.
		public const Buttons None = 0;
		public const Buttons Up = Buttons.DPadUp | Buttons.LeftThumbstickUp;
		public const Buttons Down = Buttons.DPadDown | Buttons.LeftThumbstickDown;
		public const Buttons Left = Buttons.RightThumbstickLeft;
		public const Buttons Right = Buttons.RightThumbstickRight;
		//public const Buttons Left = Buttons.DPadLeft | Buttons.LeftThumbstickLeft;
		//public const Buttons Right = Buttons.DPadRight | Buttons.LeftThumbstickRight;
		public const Buttons TurnLeft = Buttons.DPadLeft | Buttons.LeftThumbstickLeft;
		public const Buttons TurnRight = Buttons.DPadRight | Buttons.LeftThumbstickRight;
		public const Buttons UpLeft = Up | Left;
		public const Buttons UpRight = Up | Right;
		public const Buttons DownLeft = Down | Left;
		public const Buttons DownRight = Down | Right;
		public const Buttons Any = Up | Down | Left | Right | TurnLeft | TurnRight;

		/// <summary>
		/// Gets the current direction from a game pad and keyboard.
		/// </summary>
		public static Buttons FromInput(GamePadState gamePad, KeyboardState keyboard) {
			Buttons direction = None;

			// Get vertical direction.
			if (gamePad.IsButtonDown(Buttons.DPadUp) ||
				gamePad.IsButtonDown(Buttons.LeftThumbstickUp) ||
				keyboard.IsKeyDown(Keys.Up) ||
				keyboard.IsKeyDown(Keys.W)) {
				direction |= Up;
			} else if (gamePad.IsButtonDown(Buttons.DPadDown) ||
				  gamePad.IsButtonDown(Buttons.LeftThumbstickDown) ||
				  keyboard.IsKeyDown(Keys.Down) ||
				keyboard.IsKeyDown(Keys.S)) {
				direction |= Down;
			}

			if (gamePad.IsButtonDown(Buttons.RightThumbstickLeft) ||
				keyboard.IsKeyDown(Keys.Q)) {
				direction |= Left;
			} else if (gamePad.IsButtonDown(Buttons.RightThumbstickRight) ||
				keyboard.IsKeyDown(Keys.E)) {
				direction |= Right;
			}

			// Comebine with horizontal direction.
			if (gamePad.IsButtonDown(Buttons.DPadLeft) ||
				gamePad.IsButtonDown(Buttons.LeftThumbstickLeft) ||
				keyboard.IsKeyDown(Keys.Left) ||
				keyboard.IsKeyDown(Keys.A)) {
				direction |= TurnLeft;
			} else if (gamePad.IsButtonDown(Buttons.DPadRight) ||
				  gamePad.IsButtonDown(Buttons.LeftThumbstickRight) ||
				  keyboard.IsKeyDown(Keys.Right) ||
				keyboard.IsKeyDown(Keys.D)) {
				direction |= TurnRight;
			}

			return direction;
		}

		/// <summary>
		/// Gets the direction without non-direction buttons from a set of Buttons flags.
		/// </summary>
		public static Buttons FromButtons(Buttons buttons) {
			// Extract the direction from a full set of buttons using a bit mask.
			return buttons & Any;
		}
	}
}
